use actix_web::{post, web, HttpResponse, Responder};
use rusqlite::{params, Connection};
use serde::{Deserialize, Serialize};
use serde_json::json;

#[derive(Debug, Serialize, Deserialize)]
struct Student {
    // 姓名
    id: i32,
    name: String,
    // 年级
    rank: i8,
    class: i8,
    // 宿舍
    dormitory: i8,
    dormitory_room: i16,
    // 积分
    credits: f32
}

#[post("/student/update")]
pub async fn update_student(info: web::Json<Student>) -> HttpResponse {
    let conn = match Connection::open("./data/data.db") {
        Ok(conn) => conn,
        Err(e) => {
            return HttpResponse::InternalServerError()
                .json(json!({ "error": format!("数据库连接失败: {}", e) }))
        }
    };

    match conn.execute(
        "UPDATE student SET name = ?, rank = ?, class = ?, dormitory = ?, dormitory_room = ?, credits = ? WHERE id = ?",
        [
            &info.name,
            &info.rank.to_string(),
            &info.class.to_string(),
            &info.dormitory.to_string(),
            &info.dormitory_room.to_string(),
            &info.credits.to_string(),
            &info.id.to_string(),
        ],
    ) {
        Ok(_) => HttpResponse::Ok()
            .json(json!({ "success": true, "message": format!("更新成功: {}", info.id) })),

        Err(e) => HttpResponse::InternalServerError()
            .json(json!({ "error": format!("SQL执行失败: {}", e) })),
    }
}

#[derive(Serialize)]
struct ApiResponse {
    success: bool,
    message: String,
}

#[post("/student/batch")]
async fn batch_add_students(body: String) -> impl Responder {
    let mut conn = match Connection::open("/data/data.db") {
        Ok(c) => c,
        Err(e) => return HttpResponse::InternalServerError().json(ApiResponse {
            success: false,
            message: format!("数据库连接失败: {}", e),
        })
    };

    let tx = conn.transaction().unwrap();

    for (line_num, line) in body.lines().enumerate() {
        let parts: Vec<&str> = line.split(',').map(|s| s.trim()).collect();
        
        // 验证字段数量
        if parts.len() != 7 {
            return HttpResponse::BadRequest().json(ApiResponse {
                success: false,
                message: format!("第 {} 行: 需要7个字段, 实际收到 {}", line_num + 1, parts.len()),
            });
        }

        let id = match parts[0].parse::<i32>() {
            Ok(n) => n,
            Err(_) => return HttpResponse::BadRequest().json(ApiResponse {
                success: false,
                message: format!("第 {} 行: 无效的ID格式", line_num + 1),
            })
        };

        // 解析字段
        let name = parts[1];
        let rank = match parts[2].parse::<i8>() {
            Ok(n) => n,
            Err(_) => return HttpResponse::BadRequest().json(ApiResponse {
                success: false,
                message: format!("第 {} 行: 无效的年级格式", line_num + 1),
            })
        };
        
        let class = match parts[3].parse::<i8>() {
            Ok(n) => n,
            Err(_) => return HttpResponse::BadRequest().json(ApiResponse {
                success: false,
                message: format!("第 {} 行: 无效的班级格式", line_num + 1),
            })
        };
        
        let dormitory = match parts[4].parse::<i8>() {
            Ok(n) => n,
            Err(_) => return HttpResponse::BadRequest().json(ApiResponse {
                success: false,
                message: format!("第 {} 行: 无效的宿舍楼格式", line_num + 1),
            })
        };
        
        let dormitory_room = match parts[5].parse::<i16>() {
            Ok(n) => n,
            Err(_) => return HttpResponse::BadRequest().json(ApiResponse {
                success: false,
                message: format!("第 {} 行: 无效的房间号格式", line_num + 1),
            })
        };
        
        let credits = match parts[6].parse::<f32>() {
            Ok(n) => n,
            Err(_) => return HttpResponse::BadRequest().json(ApiResponse {
                success: false,
                message: format!("第 {} 行: 无效的积分格式", line_num + 1),
            })
        };

        // 插入数据库
        if let Err(e) = tx.execute(
            "INSERT INTO students (id, name, rank, class, dormitory, dormitory_room, credits) 
            VALUES (?0, ?1, ?2, ?3, ?4, ?5, ?6)",
            params![id, name, rank, class, dormitory, dormitory_room, credits]
        ) {
            return HttpResponse::InternalServerError().json(ApiResponse {
                success: false,
                message: format!("数据库错误: {}", e),
            });
        }
    }

    tx.commit().unwrap();

    HttpResponse::Ok().json(ApiResponse {
        success: true,
        message: format!("成功添加 {} 名学生", body.lines().count()),
    })
}
